﻿using System;
using System.Text;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Savannah.Core.Test
{
    /// <summary>
    /// Az állatok mozgásának tesztelése
    /// </summary>
    [TestClass]
    public class MoveTest
    {
        /// <summary>
        /// Kreál egy 70-es túlélési és 2-es éhségszintű gazellát
        /// </summary>
        public AnimalBase CreateGazelleA()
        {
            Gazelle gazelle = new Gazelle();

            return gazelle;
        }

        /// <summary>
        /// Kreál egy 82-es túlélési és 2-es éhségszintű gazellát
        /// </summary>
        public AnimalBase CreateGazelleB()
        {
            Gazelle gazelle = new Gazelle();

            return gazelle;
        }

        /// <summary>
        /// Kreál egy 80-as túlélési és 2-es éhségszintű zsiráfot
        /// </summary>
        public AnimalBase CreateGiraffeA()
        {
            Giraffe giraffe = new Giraffe();

            return giraffe;
        }

        /// <summary>
        /// Kreál egy 89-es túlélési és 2-es éhségszintű zsiráfot
        /// </summary>
        public AnimalBase CreateGiraffeB()
        {
            Giraffe giraffe = new Giraffe();

            return giraffe;
        }

        /// <summary>
        /// Kreál egy 70-es támadási és 2-es éhségszintű oroszlánt
        /// </summary>
        public AnimalBase CreateLion()
        {
            Lion lion = new Lion();

            return lion;
        }

        /// <summary>
        /// 4X4 es nagyságú szavannát generál, melyben a növényevők az [1,0]-s koordinátájú cellára fognak lépni(kivéve ha azon vannak)
        /// </summary>
        public Cell[,] Create4X4map()
        {

            Cell[,] Map = new Cell[4, 4];

            Map[0, 0] = new Cell(FieldType.land, new Plant(1), new List<AnimalBase>(), 0, 0);
            Map[0, 1] = new Cell(FieldType.land, new Plant(1), new List<AnimalBase>(), 0, 1);
            Map[0, 2] = new Cell(FieldType.land, new Plant(1), new List<AnimalBase>(), 0, 2);
            Map[0, 3] = new Cell(FieldType.land, new Plant(0), new List<AnimalBase>(), 0, 3);
            Map[1, 0] = new Cell(FieldType.land, new Plant(12), new List<AnimalBase>(), 1, 0);
            Map[1, 1] = new Cell(FieldType.land, new Plant(1), new List<AnimalBase>(), 1, 1);
            Map[1, 2] = new Cell(FieldType.land, new Plant(1), new List<AnimalBase>(), 1, 2);
            Map[1, 3] = new Cell(FieldType.land, new Plant(1), new List<AnimalBase>(), 1, 3);
            Map[2, 0] = new Cell(FieldType.land, new Plant(1), new List<AnimalBase>(), 2, 0);
            Map[2, 1] = new Cell(FieldType.land, new Plant(1), new List<AnimalBase>(), 2, 1);
            Map[2, 2] = new Cell(FieldType.land, new Plant(1), new List<AnimalBase>(), 2, 2);
            Map[2, 3] = new Cell(FieldType.land, new Plant(1), new List<AnimalBase>(), 2, 3);
            Map[3, 0] = new Cell(FieldType.land, new Plant(0), new List<AnimalBase>(), 3, 0);
            Map[3, 1] = new Cell(FieldType.land, new Plant(1), new List<AnimalBase>(), 3, 1);
            Map[3, 2] = new Cell(FieldType.land, new Plant(1), new List<AnimalBase>(), 3, 2);
            Map[3, 3] = new Cell(FieldType.land, new Plant(0), new List<AnimalBase>(), 3, 3);

            return Map;
        }

        /// <summary>
        /// 3X1-es szavannát gyárt lépések teszteléséhez, amiben a 0,3-as koordinátájú cella a legkedvezőbb a növényevőknek(feltéve ha nem rajta tartózkodik)
        /// </summary>
        public Cell[,] CreateSmallMap()
        {
            Cell[,] cells = new Cell[3, 1];

            cells[0, 0] = new Cell(FieldType.land, new Plant(1), new List<AnimalBase>(), 0, 0);

            cells[1, 0] = new Cell(FieldType.land, new Plant(1), new List<AnimalBase>(), 1, 0);

            cells[2, 0] = new Cell(FieldType.land, new Plant(8), new List<AnimalBase>(), 2, 0);

            return cells;
        }


        [TestMethod]
        public void MoveTestGazelleA()
        {
            Gazelle gazelle = (Gazelle)CreateGazelleA();
            gazelle.xCoordinate = 0; gazelle.yCoordinate = 0;

            Cell[,] map = CreateSmallMap();
            map[0, 0].AddAnimal(gazelle);
            gazelle.Move(ref map);

            Assert.AreEqual(0, map[0, 0].GetAnimalList().Count, "nem mozdult el a gazella");
        }

        [TestMethod]
        public void MoveTestGazelleB()
        {
            Gazelle gazelle = (Gazelle)CreateGazelleA();
            gazelle.xCoordinate = 3; gazelle.yCoordinate = 3;

            Cell[,] map = Create4X4map();
            map[3, 3].AddAnimal(gazelle);
            gazelle.Move(ref map);

            Assert.AreEqual(1, map[1, 0].GetAnimalList().Count, "célt tévesztett a gazella a 4X4-es mapon");
        }

        [TestMethod]
        public void MoveTestGiraffeA()
        {
            Giraffe giraffe = (Giraffe)CreateGiraffeA();
            giraffe.xCoordinate = 1; giraffe.yCoordinate = 0;

            Cell[,] cells = CreateSmallMap();
            cells[1, 0].AddAnimal(giraffe);

            cells[1, 0].Animals[0].Move(ref cells);

            Assert.AreEqual(1, cells[2, 0].Animals.Count, "rossz helyre ment a zsiráf");
        }

        [TestMethod]
        public void MoveTestGiraffeB()
        {
            Giraffe giraffe = (Giraffe)CreateGiraffeA();
            giraffe.xCoordinate = 2; giraffe.yCoordinate = 0;


            Cell[,] cells = CreateSmallMap();
            cells[2, 0].AddAnimal(giraffe);

            cells[2, 0].Animals[0].Move(ref cells);

            Assert.AreEqual(1, cells[1, 0].Animals.Count, "nem mozdult el a zsiráf");
        }

        [TestMethod]
        public void MoveLionTestA()
        {
            Lion lion = (Lion)CreateLion();
            lion.xCoordinate = 1; lion.yCoordinate = 0;

            Gazelle victimGazelle = (Gazelle)CreateGazelleA();
            victimGazelle.xCoordinate = 0; victimGazelle.yCoordinate = 0;

            Giraffe survivorGiraffe = (Giraffe)CreateGiraffeB();
            survivorGiraffe.xCoordinate = 2; survivorGiraffe.yCoordinate = 0;

            Cell[,] cells = CreateSmallMap();
            cells[1, 0].AddAnimal(lion);
            cells[0, 0].AddAnimal(victimGazelle);
            cells[2, 0].AddAnimal(survivorGiraffe);

            lion.Move(ref cells);

            Assert.AreEqual(0, cells[1, 0].Animals.Count, "Az oroszlán nem mozdult el");
        }

        [TestMethod]
        public void MoveLionTestB()
        {
            Lion lion = (Lion)CreateLion();
            lion.xCoordinate = 1; lion.yCoordinate = 0;

            Gazelle victimGazelle = (Gazelle)CreateGazelleA();
            victimGazelle.xCoordinate = 0; victimGazelle.yCoordinate = 0;

            Giraffe survivorGiraffe = (Giraffe)CreateGiraffeB();
            survivorGiraffe.xCoordinate = 2; survivorGiraffe.yCoordinate = 0;

            Cell[,] cells = CreateSmallMap();
            cells[1, 0].AddAnimal(lion);
            cells[0, 0].AddAnimal(victimGazelle);
            cells[2, 0].AddAnimal(survivorGiraffe);

            lion.Move(ref cells);

            Assert.AreEqual(2, cells[0, 0].Animals.Count, "Az oroszlán célt tévesztett");
        }

        [TestMethod]
        public void MoveTestBigMapA()
        {
            Cell[,] map = new Cell[30, 30];

            for (int i = 0; i < 30; ++i)
            {
                for (int j = 0; j < 30; ++j)
                {
                    map[i, j] = new Cell(FieldType.land, new Plant(0), new List<AnimalBase>(), i, j);
                }
            }

            map[14, 14].AddAnimal(new Giraffe(14, 14, Sex.male));

            map[10, 10] = new Cell(FieldType.land, new Plant(8), new List<AnimalBase>(), 10, 10);

            map[14, 14].Animals[0].Move(ref map);

            Assert.AreEqual(0, map[15, 15].Animals.Count, "nem mozdult az állat");
            Assert.AreEqual(1, map[10, 10].Animals.Count, "nem lépett a kellő cellára az állat");
        }

        [TestMethod]
        public void MoveTestBigMapB()
        {
            Cell[,] map = new Cell[30, 30];

            for (int i = 0; i < 30; ++i)
            {
                for (int j = 0; j < 30; ++j)
                {
                    map[i, j] = new Cell(FieldType.land, new Plant(0), new List<AnimalBase>(), i, j);
                }
            }

            Giraffe subject = new Giraffe(2, 2, Sex.female);

            map[2, 2].AddAnimal(subject);

            map[9, 2] = new Cell(FieldType.land, new Plant(10), new List<AnimalBase>(), 9, 2);

            map[2, 2].Animals[0].Move(ref map);

            Assert.AreEqual(map[9, 2], map[7, 2].Animals[0].targetCell, "nem célozta meg következő körre a kellő cellát");
            Assert.AreEqual(1, map[7, 2].Animals.Count, "nem lépett a kellő cellára az állat");
            Assert.AreEqual(0, map[2, 2].Animals.Count, "nem lépett le a celláról az állat(vagy csak nem került levételre)");

            map[7, 2].Animals[0].Move(ref map);

            Assert.AreEqual(null, map[9, 2].Animals[0].targetCell, "nem célozta meg következő körre a kellő cellát (másodjára lépett)");
            Assert.AreEqual(1, map[9, 2].Animals.Count, "nem lépett a kellő cellára az állat (másodjára lépett)");
            Assert.AreEqual(0, map[7, 2].Animals.Count, "nem lépett le a celláról az állat(vagy csak nem került levételre) másodjára lépett!!!");
        }

        [TestMethod]
        public void MoveTestBigMapC()
        {
            Cell[,] map = new Cell[30, 30];

            for (int i = 0; i < 30; ++i)
            {
                for (int j = 0; j < 30; ++j)
                {
                    map[i, j] = new Cell(FieldType.land, new Plant(0), new List<AnimalBase>(), i, j);
                }
            }

            Giraffe subject = new Giraffe(27, 2, Sex.female);

            map[27, 2].AddAnimal(subject);

            map[29, 2] = new Cell(FieldType.land, new Plant(10), new List<AnimalBase>(), 29, 2);

            map[27, 2].Animals[0].Move(ref map);

            Assert.AreEqual(1, map[29, 2].Animals.Count, "nem lépett a kellő cellára az állat");
            Assert.AreEqual(0, map[27, 2].Animals.Count, "nem lépett le a celláról az állat(vagy csak nem került levételre)");
        }
    }
}
